-- Decompiled with the Synapse X Luau decompiler.

local M = _G.ServerOHOH.class.new(script);
local v2 = {};
local DataBaseType = {};
local DataBase = {
	normal = {}, 
	sort = {}
};
local DataStoreService = game:GetService("DataStoreService");
function M.CreateDataBase(self, p2)
	assert(p2, "param name is nil");
	assert(not DataBaseType[p2], "data base named " .. tostring(p2) .. " is existed");
	
	DataBase.normal[p2] = DataStoreService:GetDataStore(p2);
	DataBaseType[p2] = "normal";
end;
function M.CreateSortDataBase(self, p4)
	assert(p4, "param name is nil");
	assert(not DataBaseType[p4], "data base named " .. tostring(p4) .. " is existed");
	DataBase.sort[p4] = DataStoreService:GetOrderedDataStore(p4);
	DataBaseType[p4] = "sort";
end;

local function number2string(p5)
	if type(p5) ~= "table" then
		return p5;
	end;
	local v3 = {};
	
	for k,v in pairs(p5) do
		if type(k) == "number" then
			v3[tostring(k)]=number2string(v)
		else
			v3[k]=number2string(v)
		end
	end
	
	return v3
end;

local function string2number(p6)
	if type(p6) ~= "table" then
		return p6;
	end;
	local v9 = {};
	for v10, v11 in pairs(p6) do
		v9[tonumber(v10) or v10] = string2number(v11);
	end;
	return v9;
end;

--db, userId, callBack, cmd
local isSaveData =true-- _G.ServerOHOH.config.ProjectConfig.IsSaveData
local function Operate(db, userId, callBack, cmd) --userId 意义为存储ID，删除历史购买失败记录（比如）
	if not isSaveData then
		return
	end
	local data = nil;
	data = callBack();
	if cmd == "save" then
		--assert(data,"data==nil")
		if data == nil then
			db:RemoveAsync(userId);
			--warn("删除数据成功！：",userId)
			return;
		else
			--warn("更新数据！：",userId)
			db:SetAsync(userId, number2string(data));
			return;
		end;
	end;
	if cmd == "increment" then
		local v13 = tonumber(data);
		assert(v13, "increment value must be a number");
		db:IncrementAsync(userId, v13);
	end;
end;


local u16 = {};
local Save_Data_Queue = {};

local EnumDataStoreRequestType = {
	normal = Enum.DataStoreRequestType.SetIncrementAsync, 
	sort = Enum.DataStoreRequestType.SetIncrementSortedAsync
};
local Data_Key_UserId_Buffer = {};

local function OperateDataBase(db, userId, callBack, cmd)
	local v14, v15 = xpcall(Operate, debug.traceback, db, userId, callBack, cmd);
	if not v14 then
		warn(v15);
	end;
end;

local IS_SAVING = nil;
local function runSave()
	while true do
		--检测运行时间
		local v16 = os.clock();
		for v17, v18 in pairs(u16) do
			for v19, v20 in pairs(v18) do
				if v16 - v20 > 10 then
					v18[v19] = nil;
				end;
			end;
		end;
		
		local v21 = 1;
		for v22 = 1, #Save_Data_Queue do
			local operate = Save_Data_Queue[v21];
			if not operate then
				break;
			end;
			
			--dataKey, userId, callBack, "save"
			local dataKey, userId, callBack, cmd = table.unpack(operate);
			if u16[dataKey] and u16[dataKey][userId] then
				v21 = v21 + 1;
			elseif DataStoreService:GetRequestBudgetForRequestType(EnumDataStoreRequestType[DataBaseType[dataKey]]) < 1 then
				v21 = v21 + 1;
			else
				u16[dataKey] = u16[dataKey] or {};
				u16[dataKey][userId] = os.clock();
				Data_Key_UserId_Buffer[dataKey][userId] = nil;
				table.remove(Save_Data_Queue, v21);
				coroutine.wrap(OperateDataBase)(DataBase[DataBaseType[dataKey]][dataKey], userId, callBack, cmd);
			end;
		end;
		if true then
			wait(1);
		end;	
	end;
	IS_SAVING = nil;
end;

--DataBaseManager:Save(OHOHEnum.data_base.player_data, obj:GetUserId(), function()
--	return self.__save_data.__real;
--end);
function M.Save(self, dataKey, userId, callBack)
	assert(dataKey, "param name is nil");
	assert(userId, "param key is nil");
	assert(callBack, "param get value function is nil");
	assert(type(callBack) == "function", "get value function must be a function");
	assert(DataBaseType[dataKey], "no such database named ", dataKey);
	if Data_Key_UserId_Buffer[dataKey] and Data_Key_UserId_Buffer[dataKey][userId] then
		return;
	end;
	Data_Key_UserId_Buffer[dataKey] = Data_Key_UserId_Buffer[dataKey] or {};
	Data_Key_UserId_Buffer[dataKey][userId] = true;
	table.insert(Save_Data_Queue, { dataKey, userId, callBack, "save" });

	if not IS_SAVING then
		IS_SAVING = true;
		coroutine.wrap(runSave)();
	end;
end;

function M.Clear(self, dataKey, userId, callBack)
	assert(dataKey, "param name is nil");
	assert(userId, "param key is nil");
	assert(callBack, "param get value function is nil");
	assert(type(callBack) == "function", "get value function must be a function");
	assert(DataBaseType[dataKey], "no such database named ", dataKey);
	DataBase[DataBaseType[dataKey]][dataKey]:RemoveAsync(userId)
	--DataBaseType[dataKey]:RemoveAsync(userId);
	isSaveData=false
	
	print("删除数据成功！：",userId)
	callBack()
end

function M.Increment(p19, p20, p21, p22)
	assert(p20, "param name is nil");
	assert(p21, "param key is nil");
	assert(p22, "param num is nil");
	assert(DataBaseType[p20], "no such database named ", p20);
	if Data_Key_UserId_Buffer[p20] and Data_Key_UserId_Buffer[p20][p21] then
		return;
	end;
	local v28 = {};
	v28[1] = p20;
	v28[2] = p21;
	v28[3] = function()
		return p22;
	end;
	v28[4] = "increment";
	Data_Key_UserId_Buffer[p20] = Data_Key_UserId_Buffer[p20] or {};
	Data_Key_UserId_Buffer[p20][p21] = true;
	table.insert(Save_Data_Queue, v28);
	if not IS_SAVING then
		IS_SAVING = true;
		coroutine.wrap(runSave)();
	end;
end;
function M.IsSaving(p23)
	return IS_SAVING;
end;
local u26 = {
	normal = Enum.DataStoreRequestType.GetAsync, 
	sort = Enum.DataStoreRequestType.GetSortedAsync
};
function M.Load(p24, p25, p26)
	local v29 = nil;
	assert(p25, "param name is nil");
	assert(p26, "param key is nil");
	local v30 = DataBase[DataBaseType[p25]][p25];
	assert(v30, "no such database named " .. p25);
	if DataStoreService:GetRequestBudgetForRequestType(u26[DataBaseType[p25]]) < 1 then
		return false, "out of load queue";
	end;
	local v31 = nil;
	v31, v29 = xpcall(v30.GetAsync, debug.traceback, v30, p26);
	if not v31 then
		warn(v29);
		return v31, v29;
	end;
	return v31, string2number(v29);
end;

local function u28(p27, p28, p29, p30, p31)
	local v32, v33 = xpcall(p27.GetSortedAsync, debug.traceback, p27, p28, p29, p30, p31);
	return v32, v33;
end;

--minValue
--可选参数。如果设置，数据页小于 minValue 的会被排除。
--maxValue
--可选参数。如果设置，数据页大于 maxValue 的会被排除。
function M.GetSortedList(self, key, isAscending, count, minValue, maxValue)
	local v34 = nil;
	assert(key, "param name is nil");
	assert(isAscending ~= nil, "param ascending is nil");
	assert(count, "param num is nil");
	if DataStoreService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetSortedAsync) < 1 then
		return false, "out of load queue";
	end;
	local v35 = nil;
	v35, v34 = u28(DataBase[DataBaseType[key]][key], isAscending, count, minValue, maxValue);
	if not v35 then
		warn(v34);
		return false, v34;
	end;
	local v36 = 0;
	if not v34 then
		return false, "get data faild";
	end;
	local v37 = {};
	while true do
		for v38, v39 in ipairs(v34:GetCurrentPage()) do
			table.insert(v37, v39);
			if count <= #v37 then
				return v37;
			end;
		end;
		if v34.IsFinished then
			break;
		end;
		local v40 = os.clock();
		if v40 - v36 < 10 then
			wait(10 - (v40 - v36));
		end;
		v36 = v40;
		v34:AdvanceToNextPageAsync();	
	end;
	return v37;
end;
return M;
